package com.hospital.register.common.exception;

import com.hospital.register.common.result.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.sql.DataTruncation;

/**
 * 全局异常处理器
 *
 * @author 原作者、刘逸晖
 */
@ControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 日志记录器
     */
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 处理校验异常
     *
     * @param bindException 异常
     * @return 错误信息
     */
    @ExceptionHandler(BindException.class)
    @ResponseBody
    public Result handleBindException(BindException bindException) {
        Result result = Result.fail();
        result.setMessage(bindException.getAllErrors().get(0).getDefaultMessage());
        this.logger.error("抱歉，" + result.getMessage());
        return result;
    }

    /**
     * 处理校验异常
     *
     * @param constraintViolationException 异常
     * @return 错误信息
     */
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseBody
    public Result handleConstraintViolationException(ConstraintViolationException constraintViolationException) {
        Result result = Result.fail();
        for (ConstraintViolation constraintViolation : constraintViolationException.getConstraintViolations()) {
            result.setMessage(constraintViolation.getMessage());
            this.logger.error("抱歉，" + result.getMessage());
            continue;
        }
        return result;
    }

    /**
     * 处理校验异常
     *
     * @param exception 异常对象
     * @return 错误信息
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public Result handleMethodArgumentNotValidException(MethodArgumentNotValidException exception) {
        Result result = Result.fail();
        result.setMessage(exception.getBindingResult().getAllErrors().get(0).getDefaultMessage());
        this.logger.error("抱歉，" + result.getMessage());
        return result;
    }

    /**
     * 处理业务异常
     *
     * @param businessException 异常
     * @return 错误信息
     */
    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    public Result handleBusinessException(BusinessException businessException) {
        Result result = Result.fail();
        result.setMessage(businessException.getMessage());
        return result;
    }

    /**
     * 处理 sql 参数过长的异常
     *
     * @param dataTruncation 异常
     * @return 错误结果
     */
    @ExceptionHandler(DataTruncation.class)
    @ResponseBody
    public Result handleDataTruncation(DataTruncation dataTruncation) {
        Result result = Result.fail();
        result.setMessage("抱歉，参数过长");
        this.logger.error(dataTruncation.getMessage());
        return result;
    }

    /**
     * 处理所有异常
     *
     * @param exception 异常
     * @return 错误结果
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Result handleException(Exception exception) {
        exception.printStackTrace();
        Result result = Result.fail();
        result.setMessage("未知错误");
        return result;
    }

}
